package org.jeecg.modules.online.graphreport.service.impl;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import com.alibaba.fastjson.JSON;
import org.apache.commons.lang.StringUtils;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.system.api.ISysBaseAPI;
import org.jeecg.common.system.vo.DictModel;
import org.jeecg.modules.online.cgform.util.CgformUtil;
import org.jeecg.modules.online.graphreport.entity.OnlGraphreportHead;
import org.jeecg.modules.online.graphreport.entity.OnlGraphreportItem;
import org.jeecg.modules.online.graphreport.entity.OnlGraphreportTemplet;
import org.jeecg.modules.online.graphreport.entity.OnlGraphreportTempletItem;
import org.jeecg.modules.online.graphreport.mapper.OnlGraphreportHeadMapper;
import org.jeecg.modules.online.graphreport.service.IOnlGraphreportApiService;
import org.jeecg.modules.online.graphreport.service.IOnlGraphreportHeadService;
import org.jeecg.modules.online.graphreport.service.IOnlGraphreportItemService;
import org.jeecg.modules.online.graphreport.service.IOnlGraphreportTempletItemService;
import org.jeecg.modules.online.graphreport.service.IOnlGraphreportTempletService;
import org.jeecg.modules.online.graphreport.util.GraphreportUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

/**
 * @Description: 图表报告
 * @Author:jeecg-boot
 * @Date: 2019-04-10
 * @Version:V1.0
 */
@Service("onlGraphreportApiServiceImpl")
public class OnlGraphreportApiServiceImpl extends ServiceImpl<OnlGraphreportHeadMapper, OnlGraphreportHead> implements IOnlGraphreportApiService {

	@Autowired
	private IOnlGraphreportHeadService headService;
	@Autowired
	private IOnlGraphreportItemService itemService;

	@Autowired
	private IOnlGraphreportTempletService templetService;
	@Autowired
	private IOnlGraphreportTempletItemService templetItemService;

	@Autowired
	private ISysBaseAPI sysBaseAPI;

	@Override
	public Result<?> getTempletChartsData(String id) {
		Map<String, Object> resultMap = new HashMap<String, Object>();
		// 根据templetId查询模板数据
		OnlGraphreportTemplet templet = templetService.getById(id);
		if (templet == null) {
			return Result.error("未找到对应实体");
		}
		resultMap.put("templet", templet);

		// 查询出当前模板的所有子项
		List<OnlGraphreportTempletItem> templetItems = templetItemService.selectByMainId(id);
		// selectByMainId(id);

		// 遍历子项进行分组
		Iterator<OnlGraphreportTempletItem> iterator = templetItems.iterator();

		List<Object> groups = new ArrayList<>();
		List<Object> group = null;

		Integer groupNum = null;
		String groupStyle = null;
		String groupTxt = null;
		while (iterator.hasNext()) {
			OnlGraphreportTempletItem templetItem = iterator.next();

			// 如果groupNum不匹配，则新建分组
			if (groupNum == null || !templetItem.getGroupNum().equals(groupNum)) {
				if (group != null) {
					groups.add(this.getGroupMap(groupNum, groupStyle, groupTxt, group));
				}
				group = new ArrayList<>();
				groupNum = templetItem.getGroupNum();
				groupStyle = templetItem.getGroupStyle();
				groupTxt = templetItem.getGroupTxt();
			}
			// 获取图表数据
			String code = templetItem.getGraphreportCode();
			OnlGraphreportHead head = headService.queryByCode(code);
			// 判断图表类型
			String graphreportType = templetItem.getGraphreportType();
			if (!"normal".equals(graphreportType)) {
				head.setGraphType(graphreportType);
			}
			// 获取数据
			Map<String, Object> chartMap = this.queryChartDataSource(head, null);
			group.add(chartMap);
		}
		groups.add(this.getGroupMap(groupNum, groupStyle, groupTxt, group));

		resultMap.put("groups", groups);
		return Result.ok(resultMap);
	}

	/** 获取分组对象 */
	private Map<String, Object> getGroupMap(int groupNum, String groupStyle, String groupTxt, List<?> group) {
		Map<String, Object> groupMap = new HashMap<String, Object>();
		groupMap.put("groupNum", groupNum);
		groupMap.put("groupStyle", groupStyle);
		groupMap.put("groupTxt", groupTxt);
		groupMap.put("charts", group);
		return groupMap;
	}

	/** 执行sql语句，获取图表数据 */
	@Override
	public Map<String, Object> queryChartDataSource(OnlGraphreportHead head, String paramString) {

		Map<String, Object> resultMap = new HashMap<String, Object>();
		resultMap.put("head", head);
		//手工将字段都转为小写，为了兼容各种数据库
		if (head.getYaxisField() != null) {
			head.setYaxisField(head.getYaxisField().toLowerCase());
		}
		if (head.getXaxisField() != null) {
			head.setXaxisField(head.getXaxisField().toLowerCase());
		}

		// 根据headId查询出items
		List<OnlGraphreportItem> items = itemService.selectByMainId(head.getId());
		//手工将字段都转为小写，为了兼容各种数据库
		for (OnlGraphreportItem i : items) {
			if (i.getFieldName() != null) {
				i.setFieldName(i.getFieldName().toLowerCase());
			}
		}

		// 字典 map
		Map<String, Object> dictOptions = new HashMap<>(0);

        for (OnlGraphreportItem item : items) {
            String dictCode = item.getDictCode();
            if (!StringUtils.isEmpty(dictCode)) {

                List<DictModel> dictList = null;
                // 判断字典是否是 select 开头的，如果是就认定为是一个 sql 语句，执行该语句获取数据并当做字典使用
                if (dictCode.toLowerCase().trim().indexOf("select ") == 0) {
                    List<Map<String, Object>> queryDictList = headService.executeSelete(dictCode);
                    if (queryDictList != null && queryDictList.size() != 0) {
                        item.setDictCode(item.getFieldName());
                        // 通过 fastJson 转为 java DictModel对象
                        String queryDictJson = JSON.toJSONString(queryDictList);
                        dictList = JSON.parseArray(queryDictJson, DictModel.class);
                    }
                } else {
                    // 普通字典
                    dictList = sysBaseAPI.queryDictItemsByCode(dictCode);
                }
				dictOptions.put(item.getDictCode(), dictList);
            }
        }

		resultMap.put("items", items);
		resultMap.put("dictOptions", dictOptions);

		// 判断数据模式是否是sql，如果是就执行sql语句
		String dataType = "sql";
		if (dataType.equals(head.getDataType())) {
			String sql = head.getCgrSql();

			// 拼装查询条件SQL
			String conditionSql = GraphreportUtil.getSplicingConditionSql(sql, paramString);

			// 执行SQL语句
			List<Map<String, Object>> listMap = headService.executeSelete(conditionSql);
			//手工将字段都转为小写，为了兼容各种数据库
			resultMap.put("data", CgformUtil.toLowerCasePageList(listMap));
		}
		return resultMap;
	}

}
